<template>
  <div class="add-logo">
    <template v-if="!src">
      <div class="icon-box" :class="[dropEnterClass]" @drop="drop" @dragenter="dragenter" @dragleave="dragleave" v-loading="loading">
        <el-icon size="50px">
          <Plus />
        </el-icon>
        <input @change="drop" class="file-input" type="file" accept="image/jpeg,image/jpg,image/png" title="" />
      </div>
      <p class="desc">选择一张图片，或拖拽一张图片到上方框内</p>
      <p class="tips">支持JPG/JPEG/PNG格式</p>
      <p class="tips">
        注: 请保证导入的图片为最佳分辨率以适配照片缩放不模糊
      </p>
    </template>
    <template v-else>
      <div class="preview-box">
        <div class="img-box">
          <img :src="src" />
        </div>
      </div>
      <div class="style-item">
        <el-radio-group v-model="styleType" class="radios" @change="styleChange">
          <el-radio label="1" size="large">保持原样</el-radio>
          <el-radio label="2" size="large">使用圆角</el-radio>
        </el-radio-group>
      </div>
    </template>
    <div class="tool-bar">
      <el-button @click="onMenuClick('cancel')" class="btn" :type="src ? 'default' : 'primary'" size="default">取消</el-button>
      <el-button @click="onMenuClick('throw-away')" class="btn" type="primary" size="default" v-if="src">重新选择</el-button>
      <el-button @click="onMenuClick('confirm')" class="btn" type="danger" size="default" v-if="src">立即添加</el-button>
    </div>
  </div>
</template>


<script setup>
  import { onMounted, ref, defineEmits, onBeforeUnmount } from 'vue'
  const fs = require('fs')
  const remote = require("@electron/remote")
  const sharp = require("sharp")

  const $emit = defineEmits(['menu-click'])
  const dropEnterClass = ref('') // 拖拽样式
  const styleType = ref('1') // logo风格
  const logoFileBufs = {
    '1': null,
    '2': null
  }
  const src = ref('') // 图标路径
  let startSharp = null
  let logoRect = {
    width: 0,
    height: 0,
  }
  let saveFileName = ''
  const loading = ref(false)



  const styleChange = value => {
    src.value = window.URL.createObjectURL(new Blob([logoFileBufs[value]], {type: 'application/png'}))
  }

  // 禁用调浏览器默认的拖拽事件
  const preventDefault = e => {
    e.preventDefault()
  }


  
  onMounted(() => {
    //拖离
    document.addEventListener('dragleave', preventDefault)
    //拖后放
    document.addEventListener('drop', preventDefault)
    //拖进
    document.addEventListener('dragenter', preventDefault)
    //拖来拖去
    document.addEventListener('dragover', preventDefault)

    window.URL.revokeObjectURL(src.value)
  })

  onBeforeUnmount(() => {
    //拖离
    document.removeEventListener('dragleave', preventDefault)
    //拖后放
    document.removeEventListener('drop', preventDefault)
    //拖进
    document.removeEventListener('dragenter', preventDefault)
    //拖来拖去
    document.removeEventListener('dragover', preventDefault)
  })

  const drop = e => {
    e.preventDefault()
    dropEnterClass.value = ''
    const fileList =  e.dataTransfer ? e.dataTransfer.files : e.target.files
    if(fileList.length === 0 || !/\.+(jpg|jpeg|png)$/gi.test(fileList[0].name)){
      return false
    }
    loading.value = true
    const file = fileList[0]
    saveFileName = file.name.replace(/(\.(jpg|jpeg|png))$/ig, `.${Date.now()}.png`)
    const img = new Image()
    img.setAttribute('src', window.URL.createObjectURL(file))
    img.onload = () => {
      logoRect.width = img.naturalWidth
      logoRect.height = img.naturalHeight
      const limitSize = 1200
      file.arrayBuffer().then(fileData => {
        const fileBuf = Buffer.from(fileData)
        const fileSize = Math.round(file.size / 1024 / 1024)
        startSharp = sharp(fileBuf).rotate().png({quality: fileSize > 1.5 ? 60 : 100}) // rotate: 如果文件里含有exif角度，自动校正
        // 缩放，减少图片文件体积
        if (Math.min(img.naturalWidth, img.naturalHeight) > limitSize) {
          if (img.naturalHeight > img.naturalWidth) {
            logoRect.width = limitSize
            logoRect.height = Math.round(limitSize / (img.naturalWidth / img.naturalHeight))
          } else {
            logoRect.width = Math.round(limitSize / (img.naturalHeight / img.naturalWidth)),
            logoRect.height = limitSize
          }
          startSharp.resize({
            width: logoRect.width,
            height: logoRect.height,
          })
        }
        startSharp.toBuffer().then(result1 => {
          // 非圆角
          logoFileBufs['1'] = result1
          // 圆角裁剪
          const minSize = Math.min(logoRect.width, logoRect.height)
          const maxSize = Math.max(logoRect.width, logoRect.height)
          startSharp.extract({
            width: minSize,
            height: minSize,
            top: logoRect.height > logoRect.width ? Math.round((maxSize - minSize) / 2) : 0,
            left: logoRect.height > logoRect.width ? 0 : Math.round((maxSize - minSize) / 2),
          }).composite([
            {
              input: Buffer.from(`<svg><circle cx="${minSize / 2}" cy="${minSize / 2}" r="${minSize / 2}" /></svg>`),
              blend: 'dest-in'
            }
          ]).toBuffer().then(result2 => {
            src.value = window.URL.createObjectURL(new Blob([result1], {type: 'application/png'}))
            logoFileBufs['2'] = result2
            loading.value = false
          })
        })
      })
    }
    e.target.value = ''
  }


  const dragenter = e => {
    e.preventDefault()
    dropEnterClass.value = 'drag-enter'
  }

  const dragleave = e => {
    e.preventDefault()
    dropEnterClass.value = ''
  }

  // 保存logo文件到本地存储
  const saveLogo = (path) => {
    fs.writeFileSync(path + '/' + saveFileName, logoFileBufs[styleType.value])
  }

  const onMenuClick = (name) => {
    if (name === 'cancel') {
      src.value = ''
      styleType.value = '1'
    }
    if (name === 'throw-away') {
      src.value = ''
      styleType.value = '1'
    }
    if (name === 'confirm') {
      const path = remote.app.getPath('userData')
      const logoFoldPath = `${path}/assets/photo_frame_logos`
      const isFind = fs.existsSync(logoFoldPath)
      // 创建图标存储目录
      fs.mkdir(`${path}/assets`, err => {
        if (err) {
          return
        }
        fs.mkdir(logoFoldPath, err => {
          if (err) {
            return
          }
          saveLogo(logoFoldPath)
          $emit('menu-click', {
            name,
          })
        })
      })
      if (isFind) {
        saveLogo(logoFoldPath)
        $emit('menu-click', {
          name,
        })
      }
      return
    }
    $emit('menu-click', {
      name,
    })
  }
</script>



<style lang="less" scoped>
  .add-logo {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 20px;
    :deep(.el-loading-mask) {
      position: absolute !important;
      background-color: rgba(0,0,0,0.5);
    }
  }
  .icon-box,.preview-box{
    width: 180px;
    height: 180px;
    box-sizing: content-box;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    position: relative;
    border: 1px dashed #fff;
    overflow: hidden;
    &.drag-enter {
      border-color: #409EFF;
      color: #409EFF;
    }
  }
  .preview-box {
    border: none;
    background-color: #343434;
    .img-box {
      width: 80%;
      height: 80%;
      overflow: hidden;
    }
    img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
  }
  .style-item {
    padding-top: 10px;
  }
  .file-input {
    position: absolute;
    right: 0;
    bottom: 0;
    font-size: 300px;
    opacity: 0;
    cursor: pointer;
  }
  .desc {
    padding-top: 30px;
  }
  .tips {
    padding-top: 10px;
    font-size: 12px;
    &:last-child {
      color: #999;
      padding-top: 5px;
    }
  }
  .tool-bar {
    margin-top: 10px;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 15px;
    background-color: #222;
  }
</style>
